#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTextCursor>
#include <QSerialPortInfo>



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    qRegisterMetaType<QTextCursor>("QTextCursor");
    initUIs();
    initMembers();
    timer = new QTimer;
    connect(timer, SIGNAL(timeout()), this, SLOT(refulshPlot()));
    connect(timer, SIGNAL(timeout()), this, SLOT(refulshPulse()));

    timer->start(100);
}

MainWindow::~MainWindow()
{
    delete ui;
}


QStringList MainWindow::ScanSerial()
{
    QStringList ttyList ;
    foreach (const QSerialPortInfo &Info, QSerialPortInfo::availablePorts()) {
        //qDebug()<<Info.portName();
        ttyList.append(Info.portName());
    }
    return ttyList;
}


void MainWindow::initUIs()
{
    QWidget* p = takeCentralWidget();
    if(p)
        delete p;
    adj = new AdjustFrom;
    standardPlot = new CustomChart;
    childPlot = new CustomChart;
    motorDebug = new DebugForm;
    dash = new Dashboard1;
    dash->setMinimumSize(QSize(400,400));
    dash->setWindowTitle("焊枪头模拟器");
    // dash->setMaxValue(90);
    plot1 = new CustomChart;
    plot2 = new CustomChart;
    model = new QStringListModel;


    setTabPosition(Qt::LeftDockWidgetArea,QTabWidget::West);
    setDockNestingEnabled(true);

    splitDockWidget(ui->dk_left1,ui->dk_left2,Qt::Horizontal);
    tabifyDockWidget(ui->dk_dataControl,ui->dk_serial);

    ui->dk_dataControl->setWidget(adj);

    CreatDocks();
    ModifyPlots();

    ui->dk_left1->setWidget(plot1);
    ui->dk_left2->setWidget(plot2);
    auto oldsize = ui->dk_left1->size();
    ui->dk_left1->resize(ui->dk_dataControl->size());
    ui->dk_dataControl->resize(oldsize);
}

void MainWindow::initMembers()
{
    connect(adj,&AdjustFrom::creatChart,this,&MainWindow::processCharData);     // 创建曲线模型
    connect(adj,&AdjustFrom::gauShow,[this](){
            swingGau();
    });     // 创建曲线模型
}

void MainWindow::swingGau()
{
    dash->setValue(50);
    dash->show();
    PARA.exitGau.store(true);

    std::thread([this](){

        while (PARA.exitGau.load()) {
            double value = 50.00;
            int sleepCount = 0;
            int step = 10; // ms
            int wise = PARA.isWise ? 1:-1;

            s1.store(false);
            s2.store(false);
            s3.store(false);

            while (!s1.load()){
                int count = PARA.ms_start*PARA.ssc.load()/step;
                if(sleepCount >= count ){
                    s1.store(true);
                    dash->setValue(100);
                }else{
                    value  += (50.00 / count) * wise;
                    if(100 < value) value = 100;
                    sleepCount++;
                    dash->setValue(value);
                    sleep_ms(step);
                }

            }
            // qDebug()<<"------------>s1 end."<<value << "--"<< PARA.ssc.load();
            sleepCount = 0;
            while (!s2.load()) {
                if(sleepCount >= (PARA.ms_wait*PARA.ssc.load()/step)){
                    s2.store(true);
                }else{
                    sleepCount++;
                    sleep_ms(step);
                }
            }
            sleepCount = 0;
            // qDebug()<<"------------>s2 end."<<value;

            while (!s3.load()){
                int count = PARA.ms_end*PARA.ssc.load()/step;
                if(sleepCount >= count){
                    s3.store(true);
                    dash->setValue(50);
                }else{
                    value -= (50.00 / count ) * wise;
                    if(50 > value) value = 50;
                    sleepCount++;
                    dash->setValue(value);
                    sleep_ms(step);
                }

            }
            // qDebug()<<"------------>s3 end."<<value;

            sleep_ms(PARA.sleepCount);

            // PARA.isWise = !PARA.isWise;
        }
        qDebug()<<"------------>Exit Thread.";

    }).detach();


}

void MainWindow::CreatDocks()
{
    QDockWidget *dock = new QDockWidget(tr("T-摆动幅度"),this);
    dock->setFeatures(QDockWidget::DockWidgetMovable);                      //指定停靠窗体的样式，此处为可移动
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    dock->setWidget(standardPlot);
    addDockWidget(Qt::RightDockWidgetArea,dock);
    dock->setMaximumSize(QSize(166666,166666));
    // dock->setMinimumHeight(420);
    dock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
    dock->setAllowedAreas(Qt::AllDockWidgetAreas);

    QDockWidget *dockChild = new QDockWidget(tr("T-节点"),this);
    dockChild->setFeatures(QDockWidget::DockWidgetMovable);                      //指定停靠窗体的样式，此处为可移动
    dockChild->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    dockChild->setWidget(childPlot);
    addDockWidget(Qt::RightDockWidgetArea,dock);
    dockChild->setMaximumSize(QSize(166666,166666));
    // dock->setMinimumHeight(420);
    dockChild->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
    dockChild->setAllowedAreas(Qt::AllDockWidgetAreas);
    QMainWindow::tabifyDockWidget(dock,dockChild);


}

void MainWindow::ModifyPlots()
{
    plot1->setTimeCoorX();
    plot1->setYRange(0,100);
    plot1->setPenColor(QColor(185,105,154));
    plot2->setTimeCoorX();
    plot2->setYRange(0,100);
    plot2->setPenColor(QColor(185,105,154));
    plot2->setLineStyle(5);     // 设置为脉冲模式

    standardPlot->setXRange(0,1000);
    standardPlot->setYRange(0,1);
    standardPlot->setStep(true,100);
    standardPlot->setShowPoint(5);  // 设置显示数值样式-----点


    childPlot->setXRange(0,9);
    childPlot->setYRange(0,9);
    childPlot->setStep(true,1);
    standardPlot->setShowPoint(1);  // 设置显示数值样式-----点

    // 手动取消了图表的显示
//    plot1->hide();
//    plot2->hide();
    ui->dk_left1->hide();
    ui->dk_left2->hide();

}

void MainWindow::processCharData(InputPara custom)
{
    CoorData data;
    PARA.ms_start = custom.arrPuls * 2;
    PARA.sleepCount = custom.nextWait; //摆动间隔
    PARA.ms_wait =custom.sleepTime;
    PARA.ms_end = custom.backPuls * 2;

    if(PARA.ms_wait > standardPlot->getRangs().xmax){
        QMessageBox::warning(NULL, "Title", "输入数值超过限制",
                                 QMessageBox::Yes );
    }

    // 修改图表信息
    {
        double arriveSleep = (custom.arrPuls + custom.sleepTime);
        double all = arriveSleep + custom.backPuls;
        data.dataX << 0 <<  custom.arrPuls << arriveSleep << arriveSleep + custom.backPuls;
        data.dataY << 0 << 100 << 100 << 0;
        standardPlot->setXRange(0,all);
        standardPlot->setYRange(0,100);

        standardPlot->setStep(false,10);
        standardPlot->setControlData(data);
    }

    for(int i = 0;i<10;i++){
        static uint cur = 0;
        cur += rand()%3;
        if(10 <= cur){
            cur = 10;
        }
        if(9 == i){
            cur = 10;
        }
        childPlot->appendValue(i,cur);
    }


    {   // 强制终止上次显示线程
        PARA.exitGau.store(false);
        sleep_ms(500);
    }

    qDebug()<<PARA.ms_end;



}


void MainWindow::on_actionGau_triggered()
{
    dash->setValue(50);
    dash->show();
}

void MainWindow::on_actionMotor_triggered()
{
    if(Motor::GetInstance()->isDeviceOpend())
        motorDebug->show();
    else{
        QMessageBox::warning(NULL, "Warning", "电机没有连接",
                                 QMessageBox::Yes );
    }
}

void MainWindow::on_pb_connect_clicked()
{
    std::string port = ui->cb_port->currentText().toStdString();
    int bau = ui->cb_bau->currentText().toUInt(new bool);
    try {
        Motor::GetInstance()->connectDevice( "/dev/" + port,bau);
    } catch (...) {
        QMessageBox::warning(NULL, "Warning", "电机连接异常",
                                 QMessageBox::Yes );
    }

    Motor::GetInstance()->isDeviceOpend() ? ui->lb_conStatus->setText("连接成功") : ui->lb_conStatus->setText("连接失败");
    Motor::GetInstance()->setBuffSize(3);
}

void MainWindow::refulshPlot()
{
    static QDateTime oldTime = QDateTime::currentDateTime();
    double value0 = qrand() % 100;
    //读取当前时间（因为QCustomPlot支持的时间值的ms值在小数位，所以/1000.0了）
    double key = (QDateTime::currentDateTime().toMSecsSinceEpoch() - oldTime.toMSecsSinceEpoch()) / 1000.00;

    plot1->appendValue(key+8,value0);
    plot1->setXRange(key,key + 8);
    plot1->removeValue(key-8);
    plot1->updateCoor();

}

void MainWindow::refulshPulse()
{
    static QDateTime oldTime = QDateTime::currentDateTime();
    double value0 = qrand() % 100;
    //读取当前时间（因为QCustomPlot支持的时间值的ms值在小数位，所以/1000.0了）
    double key = (QDateTime::currentDateTime().toMSecsSinceEpoch() - oldTime.toMSecsSinceEpoch()) / 1000.00;

    plot2->appendValue(key+8,value0);
    plot2->setXRange(key,key + 8);
    plot2->removeValue(key-8);
    plot2->updateCoor();
}

void MainWindow::on_actionScane_triggered()
{
    auto result = ScanSerial();

    if(!result.empty()){
        model->setStringList(result);
        ui->cb_port->setModel(model);
        ui->cb_port->setCurrentIndex(0);
    }else{
        qDebug()<< "未扫描到有效的串口!";
    }

}
